/*设计一个包含点类(CPoint2D)、矩形类(CRectangle)、
等腰三角形类(CTriangle)、椭圆类(CEllipse)和CDonut(圆环类)在内的形状类集合，
要求能实现形状的绘制、颜色的修改以及缩放、上下左右移动等操作。
基于Graph2D图形库编写测试程序，从键盘输入下列测试数据
（数据格式为形状类型，形状位置、尺寸与颜色，Exit为结束符），
创建多个不同颜色、位置和大小的形状对象，进行缩放、平移等操作。*/

//shape：中心位置，颜色，移动，缩放，获取位置
#include<iostream>
#include<vector>
#include<memory>
#include<sstream>
#include<string>
#include<iomanip>
using namespace std;
class Shape
{
    protected:
    unsigned long color;
    double x,y;
    public:
    Shape(unsigned long c,double _x,double _y):color(c),x(_x),y(_y){}
    virtual ~Shape(){}//shape作为虚函数的必要性
    
    void setColor(unsigned long c){color=c;}
    unsigned long getColor()const{return color;}
   
    //移动
    virtual void move (double dx,double dy)
    {
        x+=dx;
        y+=dy;
    }
    
    //绘制操作
    virtual void draw()const=0;//???
    //获取位置
    void getPosition(double &xpos,double &ypos)
    {
        xpos=x;
        ypos=y;
        //这是什么操作？
    }
};
//点类
class CPoint2D:public Shape 
{
    public:
    CPoint2D(unsigned long c,double _x,double _y):Shape(c,_x,_y){}
   //点的大小不做改变
    void draw()const 
    {
   cout<<"drawing point at:("<<x<<","<<y<<")with color"<<color<<endl;
   //实际调用图形库绘制点
    }
};
//矩形
class CRectangle:public Shape
{
  private:
  double width,height;
  public:
    CRectangle(unsigned long c,double _x,double _y,
    double _w,double _h):Shape(c,_x,_y),width(_w),height(_h){}
    void scale(double factor)
     {
    width*=factor;
    height*=factor;
    }
    void draw()const 
    {
   cout<<"drawing rectangle at:("<<x<<","<<y<<")with size"
   <<width<<"*"<<height<<"and color"<<color<<endl;
    }

};
//等腰三角形
class CTriangle:public Shape
{
  private:
  double base,height;
  public:
    CTriangle(unsigned long c,double _x,double _y,
    double _b,double _h):Shape(c,_x,_y),base(_b),height(_h){}
    void scale(double factor)
     {
    base*=factor;
    height*=factor;
    }
    void draw()const override
    {
   cout<<"drawing triangle at:("<<x<<","<<y<<")with base"
   <<base<<"and height"<<height<<"and color"<<color<<endl;
    }

};
//椭圆类
class CEllipse:public Shape
{
    private:
  double a,b;
  public:
    CEllipse(unsigned long c,double _x,double _y,
    double _a,double _b):Shape(c,_x,_y),a(_a),b(_b){}
    void scale(double factor)
     {
    a*=factor;
    b*=factor;
    }
    void draw()const 
    {
   cout<<"drawing triangle at:("<<x<<","<<y<<")with axes"
   <<a<<"and"<<b<<"and color"<<color<<endl;
    }

};
//圆环
class CDonut:public Shape
{
  double inner,outer;
  public:
  CDonut(unsigned long c,double _x,double _y,
    double _i,double _o):Shape(c,_x,_y),inner(_i),outer(_o){}
    void scale(double factor)
     {
    inner*=factor;
    outer*=factor;
    }
    void draw()const 
    {
        cout<<"drawing donut at:("<<x<<","<<y<<")with radii"
        <<outer<<"and"<<inner<<"and color"<<color<<endl;
    }
};
int main()
{
    vector<unique_ptr<Shape>>shapes;
    //储存所有形状对象的智能指针向量，unique_ptr自动管理内存
    string line;
    while(getline(cin,line))//逐行读取直到exit
    {
        if(line=="Exit")
        break;
        istringstream iss(line);//将每行字符串转为输入流？
        string type;
        iss>>type;//首先读取形状
        //读取形状的实现
        try//try定义了一个代码区域，如果发生异常，会被catch处理
        {
           if(type=="Rectangle")
           {
            double x,y,_w,_h;
            unsigned long c;
            if(iss>>x>>y>>_w>>_h>>hex>>c>>dec)//hex  十六进制，
            //dec十进制
            {
                shapes.push_back(make_unique<CRectangle>(c,x,y,_w,_h));
                //创建智能指针管理的对象
            }
           }
           else if(type=="Ellipse") 
           {
            double x,y,_a,_b;
            unsigned long c;
            if(iss>>x>>y>>_a>>_b>>hex>>c>>dec)//hex  十六进制，dec十进制
            {
                shapes.push_back(make_unique<CRectangle>(c,x,y,_a,_b));
                //创建智能指针管理的对象
            }
           }
           else if(type=="Triangle")
           {
            double x,y,_b,_h;
            unsigned long c;
            if(iss>>x>>y>>_b>>_h>>hex>>c>>dec)//hex  十六进制，dec十进制
            {
                shapes.push_back(make_unique<CRectangle>(c,x,y,_b,_h));
                //创建智能指针管理的对象
            }
           }
           else if(type=="Donut")
           {
            double x,y,_i,_o;
            unsigned long c;
            if(iss>>x>>y>>_i>>_o>>hex>>c>>dec)//hex  十六进制，dec十进制
            {
                shapes.push_back(make_unique<CRectangle>(c,x,y,_i,_o));
                //创建智能指针管理的对象
            }
           }
           else {
            cerr<<"未知形状类型:"<<endl;}
            

        }
        catch(...)
            {
                cerr<<"输入格式错误"<<endl;
            }
       cout<<"绘制所有形状" <<endl;
       for(const auto&shape:shapes)
       {shape->draw();}

        

    }
    return 0;
}
